package com.mit.facade;

import java.util.HashMap;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.mit.common.Constants;
import com.mit.common.RequestContext;
import com.mit.common.ResultContext;
import com.mit.common.exception.BaseException;
import com.mit.common.exception.DuplicateKeyException;
import com.mit.common.exception.NoRecordUpdateException;
import com.mit.common.maintenance.dto.EmployeeDTO;
import com.mit.common.maintenance.dto.FabricCatDTO;
import com.mit.common.maintenance.dto.OrganizationDTO;
import com.mit.common.maintenance.dto.PaymentDTO;
import com.mit.common.maintenance.dto.ProductColorDTO;
import com.mit.common.maintenance.dto.ProductTypeDTO;
import com.mit.common.maintenance.dto.SeasonDTO;
import com.mit.common.maintenance.dto.UnitDTO;
import com.mit.common.security.dto.UserDTO;
import com.mit.common.token.MaintenanceTokens;
import com.mit.common.token.Tokens;
import com.mit.service.maintenance.dao.IEmployeeDAO;
import com.mit.service.maintenance.dao.IFabricCatDAO;
import com.mit.service.maintenance.dao.IOrganizationDAO;
import com.mit.service.maintenance.dao.IPaymentDAO;
import com.mit.service.maintenance.dao.IProductColorDAO;
import com.mit.service.maintenance.dao.IProductTypeDAO;
import com.mit.service.maintenance.dao.ISeasonDAO;
import com.mit.service.maintenance.dao.IUnitDAO;

public class MaintenanceFacade implements IMaintenanceFacade{
	private static final Logger logger = Logger.getLogger(MaintenanceFacade.class);
	
	private IEmployeeDAO employeeDAO;
	private IProductTypeDAO productTypeDAO;
	private IProductColorDAO productColorDAO;
	private IUnitDAO unitDAO;
	private IPaymentDAO paymentDAO;
	private IFabricCatDAO fabricCatDAO;
	private ISeasonDAO seasonDAO;
	private IOrganizationDAO organizationDAO;

	public void setOrganizationDAO(IOrganizationDAO organizationDAO) {
		this.organizationDAO = organizationDAO;
	}
	public void setSeasonDAO(ISeasonDAO seasonDAO) {
		this.seasonDAO = seasonDAO;
	}
	public void setFabricCatDAO(IFabricCatDAO fabricCatDAO) {
		this.fabricCatDAO = fabricCatDAO;
	}

	public void setUnitDAO(IUnitDAO unitDAO) {
		this.unitDAO = unitDAO;
	}

	public void setPaymentDAO(IPaymentDAO paymentDAO) {
		this.paymentDAO = paymentDAO;
	}

	public void setProductColorDAO(IProductColorDAO productColorDAO) {
		this.productColorDAO = productColorDAO;
	}

	public IProductTypeDAO getProductTypeDAO() {
		return productTypeDAO;
	}

	public void setProductTypeDAO(IProductTypeDAO productTypeDAO) {
		this.productTypeDAO = productTypeDAO;
	}

	public IEmployeeDAO getEmployeeDAO() {
		return employeeDAO;
	}

	public void setEmployeeDAO(IEmployeeDAO employeeDAO) {
		this.employeeDAO = employeeDAO;
	}

	@Override
	public ResultContext retrieveProductTypes(RequestContext rqs) {
		UserDTO user = rqs.getUser();
		List rtn = productTypeDAO.retrieveProductTypes(user.getOrgId());
		ResultContext rlt = new ResultContext();
		rlt.addResult(MaintenanceTokens.KEY_PRD_TYPE_LIST, rtn);
		return rlt;
	}

	@Override
	public ResultContext updateProductTypes(RequestContext rqs) throws NoRecordUpdateException {
		UserDTO user = rqs.getUser();
		List<ProductTypeDTO> lst = (List<ProductTypeDTO>) rqs.getParameter(MaintenanceTokens.KEY_PRD_TYPE_LIST);
		for(ProductTypeDTO to : lst){
			if(to.getId() > 1){
				productTypeDAO.updateProductType(to);
			}else{
				to.setOrgId(user.getOrgId());
				productTypeDAO.createProductType(to);
			}
			
		}
		//Refresh List and return the the front side
		
		lst = productTypeDAO.retrieveProductTypes(user.getOrgId());
		ResultContext rlt = new ResultContext();
		rlt.addResult(MaintenanceTokens.KEY_PRD_TYPE_LIST, lst);
		return rlt;
	}

	/************** Employee Maintenance *****************/
	@Override
	public ResultContext retrieveEmployeeCount(RequestContext requestCtx) {
		UserDTO user = requestCtx.getUser();
		//String empCode = (String )rqs.getParameter(MaintenanceTokens.KEY_EMPLOYEE_CODE);
		//Integer depId = (Integer) rqs.getParameter(MaintenanceTokens.KEY_DEPARTMENT_ID);
		//Integer rc = employeeDAO.retrieveEmployeeCount(empCode, depId);
		Integer count = employeeDAO.retrieveEmployeeCount(user);
		
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(Tokens.KEY_RECORD_COUNT, count);
		return resultCtx;
	}

	@Override
	public ResultContext retrieveEmployees(RequestContext requestCtx) {
		Integer pageNo = (Integer) requestCtx.getParameter(Tokens.KEY_PAGE_NO);
		Integer pageSize = (Integer) requestCtx.getParameter(Tokens.KEY_PAGE_SIZE);
		UserDTO user = requestCtx.getUser();
		//String empCode = (String )rqs.getParameter(MaintenanceTokens.KEY_EMPLOYEE_CODE);
		//Integer depId = (Integer) rqs.getParameter(MaintenanceTokens.KEY_DEPARTMENT_ID);
		//List<EmployeeDTO> ls = employeeDAO.retrievePagingEmployee(empCode, depId, pageNo, pageSize);
		//List<EmployeeDTO> ls = employeeDAO.retrievePagingEmployee(pageNo, pageSize);
		HashMap params = new HashMap();
		params.put("orgId", user.getOrgId());
		List<EmployeeDTO> empList = employeeDAO.retrieveEmployees(params);
		
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_EMPLOYEE_LIST	, empList);
		return resultCtx;
	}
	
	@Override
	public ResultContext retrieveActiveEmployees(RequestContext requestCtx) {
		UserDTO user = requestCtx.getUser();
		HashMap params = new HashMap();
		params.put("orgId", user.getOrgId());
		params.put("isActive", Constants.DB_YES);
		List<EmployeeDTO> empList = employeeDAO.retrieveEmployees(params);
		
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_EMPLOYEE_LIST	, empList);
		return resultCtx;
	}
	
	@Override
	public ResultContext retrieveEmployeeById(RequestContext requestCtx) {
		Integer empId = (Integer) requestCtx.getParameter(MaintenanceTokens.KEY_EMPLOYEE_ID);
		EmployeeDTO employee = employeeDAO.retrieveEmployeeById(empId.intValue());
		
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_EMPLOYEE_DTO, employee);
		return resultCtx;
	}
	
	@Override
	public ResultContext deleteEmployee(RequestContext requestCtx) {
		EmployeeDTO employee = (EmployeeDTO) requestCtx.getParameter(MaintenanceTokens.KEY_EMPLOYEE_DTO);
		employeeDAO.deleteEmployeeById(employee.getId().intValue());
		return new ResultContext();
	}
	
	@Override
	public ResultContext createEmployee(RequestContext rqs) throws BaseException {
		EmployeeDTO employee = (EmployeeDTO) rqs.getParameter(MaintenanceTokens.KEY_EMPLOYEE_DTO);
		if (employeeDAO.isEmployeeExisted(employee)) {
			throw new DuplicateKeyException(StringUtils.join(new String[]{employee.getUsername(), employee.getName()}, " "));
		}
		employee = employeeDAO.createEmployee(employee);
		ResultContext result = new ResultContext();
		result.addResult(MaintenanceTokens.KEY_EMPLOYEE_DTO, employee);
		return result;
	}
	
	@Override
	public ResultContext updateEmployee(RequestContext rqs) throws BaseException {
		EmployeeDTO employee = (EmployeeDTO) rqs.getParameter(MaintenanceTokens.KEY_EMPLOYEE_DTO);
		if (employeeDAO.isEmployeeExisted(employee)) {
			throw new DuplicateKeyException(StringUtils.join(new String[]{employee.getUsername(), employee.getName()}, " "));
		}
		employee = employeeDAO.updateEmployee(employee);
		ResultContext result = new ResultContext();
		result.addResult(MaintenanceTokens.KEY_EMPLOYEE_DTO, employee);
		return result;
	}

	/************** Product Color Maintenance *****************/
	@Override
	public ResultContext retrieveProductColors(RequestContext requestCtx) {
		UserDTO user = requestCtx.getUser();
		List<ProductColorDTO> list = productColorDAO.retrieveProductColors(user.getOrgId());
		if (logger.isDebugEnabled()) {
			logger.debug("no. of list: " + list.size());
		}

		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_PRD_COLOR_LIST, list);
		return resultCtx;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ResultContext updateProductColors(RequestContext requestCtx) throws NoRecordUpdateException {
		UserDTO user = requestCtx.getUser();
		List<ProductColorDTO> list = (List<ProductColorDTO>) requestCtx.getParameter(
			MaintenanceTokens.KEY_PRD_COLOR_LIST);
		for(ProductColorDTO colorDTO : list){
			if(colorDTO.getId() > 1) {
				logger.debug("update color: " + colorDTO);
				productColorDAO.updateProductColor(colorDTO);
			} else {
				logger.debug("create color: " + colorDTO);
				colorDTO.setOrgId(user.getOrgId());
				productColorDAO.createProductColor(colorDTO);
			}
		}
		
		list = productColorDAO.retrieveProductColors(user.getOrgId());
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_PRD_COLOR_LIST, list);
		return resultCtx;
	}
	
	/************** Unit Maintenance *****************/
	@Override
	public ResultContext retrieveUnits(RequestContext requestCtx) {
		UserDTO user = requestCtx.getUser();
		List<UnitDTO> list = unitDAO.retrieveUnits(user.getOrgId());
		if (logger.isDebugEnabled()) {
			logger.debug("no. of list: " + list.size());
		}

		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_PRD_UNIT_LIST, list);
		return resultCtx;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ResultContext updateUnits(RequestContext requestCtx) throws NoRecordUpdateException {
		UserDTO user = requestCtx.getUser();
		List<UnitDTO> list = (List<UnitDTO>) requestCtx.getParameter(MaintenanceTokens.KEY_PRD_UNIT_LIST);
		for(UnitDTO unitDTO : list){
			if(unitDTO.getId() > 1) {
				logger.debug("update unit: " + unitDTO);
				unitDAO.updateUnit(unitDTO);
			} else {
				logger.debug("create unit: " + unitDTO);
				unitDTO.setOrgId(user.getOrgId());
				unitDAO.createUnit(unitDTO);
			}
		}
		
		list = unitDAO.retrieveUnits(user.getOrgId());
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_PRD_UNIT_LIST, list);
		return resultCtx;
	}
	
	/************** Payment Maintenance *****************/
	@Override
	public ResultContext retrievePayments(RequestContext requestCtx) {
		UserDTO user = requestCtx.getUser();
		List<PaymentDTO> list = paymentDAO.retrievePayments(user.getOrgId());
		if (logger.isDebugEnabled()) {
			logger.debug("no. of list: " + list.size());
		}

		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_PRD_PAYMENT_LIST, list);
		return resultCtx;
	}

	@SuppressWarnings("unchecked")
	@Override
	public ResultContext updatePayments(RequestContext requestCtx) throws NoRecordUpdateException {
		UserDTO user = requestCtx.getUser();
		List<PaymentDTO> list = (List<PaymentDTO>) requestCtx.getParameter(
			MaintenanceTokens.KEY_PRD_PAYMENT_LIST);
		for(PaymentDTO paymentDTO : list){
			if(paymentDTO.getId() > 1) {
				logger.debug("update payment: " + paymentDTO);
				paymentDAO.updatePayment(paymentDTO);
			} else {
				logger.debug("create payment: " + paymentDTO);
				paymentDTO.setOrgId(user.getOrgId());
				paymentDAO.createPayment(paymentDTO);
			}
		}
		
		list = paymentDAO.retrievePayments(user.getOrgId());
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_PRD_PAYMENT_LIST, list);
		return resultCtx;
	}
	
	/************** FabricCat Maintenance *****************/
	@Override
	public ResultContext retrieveFabricCats(RequestContext requestCtx) {
		UserDTO user = requestCtx.getUser();
		List<FabricCatDTO> list = fabricCatDAO.retrieveFabricCats(user.getOrgId());
		if (logger.isDebugEnabled()) {
			logger.debug("no. of list: " + list.size());
		}

		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_PRD_FATRIC_CAT_LIST, list);
		return resultCtx;
	}

	@Override
	public ResultContext updateFabricCats(RequestContext requestCtx) throws NoRecordUpdateException {
		UserDTO user = requestCtx.getUser();
		List<FabricCatDTO> list = (List<FabricCatDTO>) requestCtx.getParameter(
			MaintenanceTokens.KEY_PRD_FATRIC_CAT_LIST);
		for(FabricCatDTO paymentDTO : list){
			if(paymentDTO.getId() > 1) {
				logger.debug("update fabric category: " + paymentDTO);
				fabricCatDAO.updateFabricCat(paymentDTO);
			} else {
				logger.debug("create fabric category: " + paymentDTO);
				paymentDTO.setOrgId(user.getOrgId());
				fabricCatDAO.createFabricCat(paymentDTO);
			}
		}
		
		list = fabricCatDAO.retrieveFabricCats(user.getOrgId());
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_PRD_FATRIC_CAT_LIST, list);
		return resultCtx;
	}
	@Override
	public ResultContext retrieveSeasons(RequestContext rqs) {
		UserDTO user = rqs.getUser();
		ResultContext rlt = new ResultContext();
		List<SeasonDTO > lst = seasonDAO.retrieveSeasons(user.getOrgId());
		rlt.addResult(MaintenanceTokens.KEY_SEASON_LIST, lst);
		return rlt;
	}
/*	@Override
	public ResultContext testTransaction(RequestContext rqs)
			throws BaseException {
		// TODO Auto-generated method stub
		return null;
	}*/

	/************** Preference Maintenance *****************/
/*	
	@Override
	public ResultContext updatePreference(RequestContext rqs) throws BaseException {
		EmployeeDTO employee = (EmployeeDTO) rqs.getParameter(MaintenanceTokens.KEY_EMPLOYEE_DTO);
		if (employeeDAO.isEmployeeExisted(employee)) {
			throw new DuplicateKeyException(StringUtils.join(new String[]{employee.getUsername(), employee.getName()}, " "));
		}
		employee = employeeDAO.updatePreference(employee);
		ResultContext result = new ResultContext();
		result.addResult(MaintenanceTokens.KEY_EMPLOYEE_DTO, employee);
		return result;
	}*/
	
	@Override
	public ResultContext retrieveOrganization(RequestContext requestCtx) {
		Integer id = (Integer) requestCtx.getParameter(MaintenanceTokens.KEY_ORGANIZATION_ID);
		OrganizationDTO organization = organizationDAO.retrieveOrganization(id.intValue());
		
		ResultContext resultCtx = new ResultContext();
		resultCtx.addResult(MaintenanceTokens.KEY_ORGANIZATION_DTO, organization);
		return resultCtx;
	}
	
	@Override
	public ResultContext updateOrganization(RequestContext rqs) throws NoRecordUpdateException {
		OrganizationDTO organization = (OrganizationDTO) rqs.getParameter(MaintenanceTokens.KEY_ORGANIZATION_DTO);
		organization = organizationDAO.updateOrganization(organization);
		ResultContext result = new ResultContext();
		result.addResult(MaintenanceTokens.KEY_ORGANIZATION_DTO, organization);
		return result;
	}

	/************** Product Color Maintenance *****************/
}
